home *** CD-ROM | disk | FTP | other *** search
/ Total Network Tools 2002 / NextStepPublishing-TotalNetworkTools2002-Win95.iso / Archive / Misc Servers / Zope.exe / XYAP.PY < prev    next >
Encoding:
Python Source  |  1999-07-22  |  4.7 KB  |  169 lines

  1. """Yet another XML parser
  2.  
  3. This is meant to be very simple:
  4.  
  5.   - stack based
  6.  
  7.   - The parser has a table of start handlers and end handlers.
  8.  
  9.   - start tag handlers are called with the parser instance, tag names
  10.     and attributes.  The result is placed on the stack.  The default
  11.     handler places a special object on the stack (uh, a list, with the
  12.     tag name and attributes as the first two elements. ;)
  13.  
  14.   - end tag handlers are called with the object on the parser, the tag
  15.     name, and top of the stack right after it has been removed.  The
  16.     result is appended to the object on the top of the stack.
  17.  
  18. Note that namespace attributes should recieve some special handling.
  19. Oh well.
  20. """
  21.  
  22. import string
  23. from pickle import *
  24.  
  25. class xyap:
  26.     start_handlers={}
  27.     end_handlers={}
  28.  
  29.     def __init__(self):
  30.         top=[]
  31.         self._stack=_stack=[top]
  32.         self.push=_stack.append
  33.         self.append=top.append
  34.  
  35.     def handle_data(self, data): self.append(data)
  36.  
  37.     def unknown_starttag(self, tag, attrs):
  38.         if type(attrs) is ListType:
  39.             x=0
  40.             temp={}
  41.             while x<len(attrs):
  42.                 temp[attrs[x]]=attrs[x+1]
  43.                 x=x+2
  44.             attrs=temp
  45.         start=self.start_handlers
  46.         if start.has_key(tag): tag = start[tag](self, tag, attrs)
  47.         else:                  tag = [tag, attrs]
  48.         self.push(tag)
  49.         self.append=tag.append
  50.  
  51.     def unknown_endtag(self, tag):
  52.         _stack=self._stack
  53.         top=_stack[-1]
  54.         del _stack[-1]
  55.         append=self.append=_stack[-1].append
  56.         end=self.end_handlers
  57.         if end.has_key(tag): top=end[tag](self, tag, top)
  58.         append(top)
  59.  
  60. class NoBlanks:
  61.     
  62.     def handle_data(self, data):
  63.         if string.strip(data): self.append(data)
  64.  
  65. import xmllib
  66.  
  67. def struct(self, tag, data):
  68.     r={}
  69.     for k, v in data[2:]: r[k]=v
  70.     return r
  71.  
  72. def name(self, tag, data, join=string.join, strip=string.strip):
  73.     return strip(join(data[2:],''))
  74.  
  75. def tuplef(self, tag, data): return tuple(data[2:])
  76.  
  77. class XYap(xyap, xmllib.XMLParser):
  78.         def __init__(self):
  79.             xmllib.XMLParser.__init__(self)
  80.             top=[]
  81.             self._stack=_stack=[top]
  82.             self.push=_stack.append
  83.             self.append=top.append
  84.  
  85. class xmlrpc(NoBlanks, XYap, xmllib.XMLParser):
  86.     end_handlers={
  87.         'methodCall': tuplef,
  88.         'methodName': name,
  89.         'params': tuplef,
  90.         'param': lambda self, tag, data: data[2],
  91.         'value': lambda self, tag, data: data[2],
  92.         'i4':
  93.         lambda self, tag, data, atoi=string.atoi, name=name:
  94.         atoi(name(self, tag, data)),
  95.         'int':
  96.         lambda self, tag, data, atoi=string.atoi, name=name:
  97.             atoi(name(self, tag, data)),
  98.         'boolean':
  99.         lambda self, tag, data, atoi=string.atoi, name=name:
  100.             atoi(name(self, tag, data)),
  101.         'string': lambda self, tag, data, join=string.join:
  102.             join(data[2:], ''),
  103.         'double':
  104.         lambda self, tag, data, atof=string.atof, name=name:
  105.             atof(name(self, tag, data)),
  106.         'float':
  107.         lambda self, tag, data, atof=string.atof, name=name:
  108.             atof(name(self, tag, data)),
  109.         'struct': struct,
  110.         'member': tuplef,
  111.         'name': name,
  112.         'array': lambda self, tag, data: data[2],
  113.         'data': lambda self, tag, data: data[2:],
  114.         }
  115.  
  116. def test():
  117.     
  118.     data="""<?xml version="1.0"?>
  119.     <methodCall>
  120.              <methodName>examples.getStateName
  121.              </methodName>
  122.              <params>
  123.                 <param>
  124.                    <value><i4>41</i4></value>
  125.                    </param>
  126.  
  127.                 <param><value>
  128.                 <struct>
  129.              <member>
  130.                 <name>lowerBound</name>
  131.                 <value><i4>18</i4></value>
  132.                 </member>
  133.              <member>
  134.                 <name>upperBound</name>
  135.                 <value><i4>139</i4></value>
  136.                 </member>
  137.              </struct></value>
  138.                    </param>
  139.  
  140.                 <param><value>
  141.              <array>
  142.              <data>
  143.                 <value><i4>12</i4></value>
  144.                 <value><string>Egypt</string></value>
  145.                 <value><boolean>0</boolean></value>
  146.                 <value><i4>-31</i4></value>
  147.                 </data>
  148.              </array></value>
  149.                    </param>
  150.  
  151.                 </params>
  152.              </methodCall>
  153.              """
  154.     
  155.     data=string.split(data,'\n')
  156.     r=[]
  157.     for C in XYap, xmlrpc:
  158.         p=C()
  159.         for l in data:
  160.             p.feed(l)
  161.         p.close()
  162.         r.append(p._stack)
  163.     
  164.     return r
  165.  
  166.  
  167. if __name__=='__main__': print test()
  168.     
  169.